/*  HostMon/msntop - A simple program to monitor hosts on android
	Copyright (C) 2009 Devendra Laulkar

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation version 2 of the License. 

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.android.msntop;

import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import com.android.msntop.services.IPingService;
import com.android.msntop.services.IPingServiceCallBack;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class Msntop extends ListActivity {

	public static String UP = "UP";
	public static String DOWN = "DOWN";
	public static String UPDATING = "UPDATING";

	//public static final int DEFAULT_USER = 0;
	// Menu def's go here
	public static final int SETTINGS = 0;
	public static final int ADDHOST = 1;
	public static final int REFRESH = 3;
	public static final int HELP = 4;
	public static final int ABOUT = 5;
	public static final int BARCODE = 6;

	// End of menu def's
	// Intent actions and results
	public static final int HOST_VIEW=4;

	//Settings Strings
	public static final String XML_ENABLED_KEY = "isXmlLoad";
	public static final String DEFAULT_USER_KEY = "defUser";
	public static final String DEFAULT_PORT_KEY = "defPort";
	public static final String XML_WEBPATH = "xmlPathKey";
	private static final String DEFAULT_PING_KEY = "pingPackets";

	public static final int ICMP_TIMEOUT = 3000;

	public static final String HOSTS_FILE = "hosts";

	// Settings/Preferences
	private String user, xmlPath;
	boolean xmlEnabled;
	String defaultPort;
	int defNumP;

	private HostDbAdapter dbHelper;

	private static List<Host> hostList = null;
	public boolean loaded = false;
	//public boolean debug = true;

	// Stuff related to ping, threads
	String ht;
	int ht_id;
	int ht_status;
	int processed = 0;
	final Handler mHandler = new Handler(){
		// Create runnable for posting

		public void handleMessage(Message msg) {
			switch (msg.what) {

			case PING: 
				//Log.i("mHandler", "Got back request from service " + msg.obj + ":" + msg.arg1 );

				updateResultsInUi((String)msg.obj, msg.arg1);
				break;
			default:
				super.handleMessage(msg);
			}
		}
	};

	final Runnable mUpdateResults = new Runnable() {
		public void run() {
			updateResultsInUi();
		}
	};

	// Old Thread stuff
	public static int PING_ERROR = 2;
	public static int PING_OK = 0;
	public static int PING_DOWN = 1;
	protected static final int PING = 5;
	//private PingThread pingThread = new PingThread();


	// New Ping Service variables
	IPingService service = null;
	boolean serviceStatus = false;

	// End ping, thread related stuff


	private ServiceConnection serviceConn = new ServiceConnection() {

		public void onServiceConnected(ComponentName className,
				IBinder binder) {
			//Log.i("serviceConn", "Inside setting service");
			service = IPingService.Stub.asInterface(binder);

			try {
				service.registerCallback(mCallback);
				if(service != null)
				{
					serviceStatus = true;
				}
				loadHostsDisplay();
				reCheckUpdating();
			} catch (RemoteException e) {

				//Log.e("ServiceConnection:onServConn", "Got a remote exception");
			}
		}
		public void onServiceDisconnected(ComponentName className) {
			// If remote service crashes
			service = null;
			serviceStatus = false;
			//Log.e("ServiceConnection:onServConn", "Remote service crased!");
		}
	};


	/** Called when the activity is first created. */

	public synchronized void setProcessFlag(int val)
	{
		processed = val;
	}

	public synchronized int getProcessFlag()
	{
		return processed;
	}

	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		//		startService(new Intent(this, PingService.class));
		//Log.i("MSNTOP", "oncreate");
		loadSettings();
		setContentView(R.layout.host_list);
		dbHelper = new HostDbAdapter(this);
		dbHelper.open();

		if(hostList == null)
			hostList = new ArrayList<Host>();

	}

	protected void onRestart()
	{
		super.onRestart();
		//Log.i("Msntop", "OnRestart");
	}
	protected void onStart()
	{
		super.onStart();
		//Log.i("Msntop", "OnStart");
		// Start service if required
		if(!serviceStatus)
		{
			bindService();
		}
	}

	protected void onPause()
	{
		super.onPause();
		//Log.i("Msntop", "OnPause");
	}

	protected void onResume()
	{
		super.onResume();
		//Log.i("Msntop", "OnResume");
		if(!serviceStatus){
			bindService();
		}
		boolean prevXmlStatus = xmlEnabled;
		loadSettings(); // TODO - This should be done elegantly

		if(prevXmlStatus == false && xmlEnabled == true)
		{
			//			Log.i("onResume", "prevXml is false, xmlenabled is true");
			xmlLoad();
			//			Log.i("onResume", "Calling fillData");
			fillData();
		}
		else if (prevXmlStatus == true && xmlEnabled == false)
		{
			//			Log.i("onResume", "prevXml is true, xmlenabled is false");
			// Remove the data ?
		}
	}

	protected void onStop()
	{
		super.onStop();
		//Log.i("Msntop", "OnStop");
		unbindService(serviceConn);
		serviceStatus = false;
	}

	protected void onDestroy() {
		dbHelper.close();
		hostList = null;
		loaded = false;
		//Log.i("Msntop", "OnDestroy");
		if(serviceStatus)
		{
			unbindService(serviceConn);
			serviceStatus = false;
		}
		super.onDestroy();
	}


	private void loadHostsDisplay()
	{
		if(!serviceStatus)
		{
			//TODO Should we fallback to normal ping by threads ?
			Toast.makeText(Msntop.this, "Not connected to ping service, please refresh",
					Toast.LENGTH_SHORT).show();
			return;
		}
		if(hostList.size() == 0 || !loaded)
		{
			fileLoad();
			loaded = true;
		}

		if(xmlEnabled && !xmlPath.equals(getText(R.string.default_xml_webpath).toString()))
		{
			xmlLoad();
		}

		if(hostList != null)
		{
			//			Log.i("onCreate", "Calling fillData");
			fillData();
		}	
	}

	protected void reCheckUpdating()
	{
		int i;
		int n = hostList.size();

		for(i = 0; i < n; i++)
		{
			Host h = hostList.get( i );
			if( h.getOptPath() != null && h.getOptPath().length() > 0 )
			{
				isHostUrlUp( h.getName(), h.getOptPath() );
			}
			else
			{
				isHostUp2(h.getName());
			}

		}
	}

	public void bindService()
	{
		//	new Intent()


		if(bindService(new Intent("com.android.msntop.services.PINGSERVICE"),
				serviceConn, Context.BIND_AUTO_CREATE))
		{
			//Log.i("main", "Bind was done");
		}
		else
		{
			//Log.i("main", "Bind failed");
		}
	}

	public void addHost(Host host)
	{
		hostList.add(host);

	}

	public Host addHost(long id, String name, String status, String comment)
	{
		Host h = new Host(id, name, status, comment);
		hostList.add(h);
		return h;
	}

	public Host addHost(long id, String name, String status, String comment,String optPath, String sshUser, String sshPort)
	{
		Host h = new Host(id, name, status, comment, sshUser, optPath, sshPort);
		hostList.add(h);
		return h;
	}

	public void fileLoad()
	{
		Cursor cursor = dbHelper.fetchAllHosts();

		int hostCol = cursor.getColumnIndex(HostDbAdapter.KEY_HOST);
		int commentCol = cursor.getColumnIndex(HostDbAdapter.KEY_COMMENT);
		int idCol = cursor.getColumnIndex(HostDbAdapter.KEY_ROWID);
		int sshUCol = cursor.getColumnIndex(HostDbAdapter.KEY_SSHUSER);
		int sshPCol = cursor.getColumnIndex(HostDbAdapter.KEY_SSHPORT);
		int barcodeCol = cursor.getColumnIndex(HostDbAdapter.KEY_BARCODE);
		int optPathCol = cursor.getColumnIndex(HostDbAdapter.KEY_OPTPATH);

		//Log.i("msntop", "Col SSHU:" + sshUCol + " Col SSHP:" + sshPCol);
		cursor.moveToFirst();
		if(cursor.getCount() == 0)
		{
			cursor.close();
			return;
		}

		String host, comment, user, port, bc;
		int id;

		do
		{
			host = cursor.getString(hostCol); 
			comment = cursor.getString(commentCol);
			id = cursor.getInt(idCol);
			user = cursor.getString(sshUCol);
			port = cursor.getString(sshPCol);
			bc = cursor.getString(barcodeCol);
			// Change to grayed out
			Host h = addHost(id, host, UPDATING, comment,cursor.getString(optPathCol), user, port);
			h.setBarcode(bc);
			//			isHostUp(host, hostList.size() - 1);
			//isHostUp2(host);

		}while(cursor.moveToNext());

		cursor.close();
	}

	private void refresh()
	{
		hostList = new ArrayList();
		if(xmlEnabled && !xmlPath.equals(getText(R.string.default_xml_webpath).toString()))
		{
			xmlLoad();
		}
		fileLoad();
		if(hostList != null)
		{
			//			Log.i("refresh", "Calling fillData");
			fillData();
		}

		if(serviceStatus)
		{
			reCheckUpdating();
		}
		else
		{
			bindService();
		}
	}


	// Ping Service related things go here

	/**
	 * Class for interacting with the main interface of the service.
	 */
	/* Handle callbacks from remote service */
	private IPingServiceCallBack mCallback = new IPingServiceCallBack.Stub() {

		public void hostStatus(String host, int status) throws RemoteException {
			// Call handler
			Message m = mHandler.obtainMessage(PING, status, 0, host);
			mHandler.sendMessage(m);
		}
	};

	protected void isHostUp2(final String hostName)
	{
		try {
			if(serviceStatus)
			{
				service.isHostUpP(hostName, defNumP);
			}
		} catch (RemoteException e) {
			e.printStackTrace();
			//Log.e("isHostUp2", "Remote Ping service expception");
		}
	}

	protected void isHostUrlUp(final String hostName, final String optPath)
	{
		try {
			if(serviceStatus)
			{
				service.isHostUrlUp(hostName, optPath);
			}
		} catch (RemoteException e) {
			e.printStackTrace();
			//Log.e("isHostUrlUp", "Remote Ping service expception");
		}
	}
	public void xmlLoad()
	{
		URL url;
		try {
			url = new URL(xmlPath);
			InputSource ip;

			ip = new InputSource(url.openStream());
			if(ip == null)
			{
				//				Log.e("", "Bad juju, Unable to open the xml file");
			}

			/*http://www.anddev.org/parsing_xml_from_the_net_-_using_the_saxparser-t353.html */
			/* Get a SAXParser from the SAXPArserFactory. */
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();

			/* Get the XMLReader of the SAXParser we created. */
			XMLReader xr = sp.getXMLReader();
			/* Create a new ContentHandler and apply it to the XML-Reader*/
			HostHandler myExampleHandler = new HostHandler();
			xr.setContentHandler(myExampleHandler);

			/* Parse the xml-data from our URL. */
			xr.parse(ip);
			/* Parsing has finished. */

			/* Our ExampleHandler now provides the parsed data to us. */
			hostList.addAll(myExampleHandler.getData());


		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void loadSettings()
	{
		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
		user = settings.getString(DEFAULT_USER_KEY, "root");
		xmlPath = settings.getString(XML_WEBPATH, getResources().getText(R.string.default_xml_webpath).toString());
		xmlEnabled =  settings.getBoolean(XML_ENABLED_KEY, false);
		defaultPort = settings.getString(DEFAULT_PORT_KEY, "22");
		try
		{
			defNumP = Integer.parseInt(settings.getString(DEFAULT_PING_KEY, "2"));
		}
		catch(NumberFormatException e)
		{
			defNumP = 2;
		}
		//		Log.i("loadSettings", DEFAULT_USER_KEY + ":" + user + "-" + XML_WEBPATH + xmlPath +  "-" + XML_ENABLED_KEY + xmlEnabled);
	}

	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		MenuItem item;

		item = menu.add(0, ADDHOST,0, R.string.add_host);
		item.setIcon(android.R.drawable.ic_menu_add);
		item = menu.add(0, REFRESH,0, R.string.refresh);
		item.setIcon(android.R.drawable.ic_menu_rotate);

		item = menu.add(0, SETTINGS,0, R.string.settings);
		item.setIcon(android.R.drawable.ic_menu_preferences);
		item = menu.add(0, HELP,0, R.string.help);
		item.setIcon(android.R.drawable.ic_menu_help);

		item = menu.add(0, ABOUT,0, R.string.about);
		item.setIcon(android.R.drawable.ic_menu_info_details);

		item = menu.add(0, BARCODE,0, R.string.lookupBarcode);
		item.setIcon(R.drawable.barcode);

		return true;
	}

	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch(item.getItemId()) {
		case SETTINGS:

			launchSettings();

			break;
		case ADDHOST:
			createHost();
			break;

		case REFRESH:
			refresh();
			break;

		case HELP:
			displayHelp();
			break;
		case ABOUT:
			displayAbout();
			break;

		case BARCODE:
			checkBarcode();
			break;
		}

		return super.onMenuItemSelected(featureId, item);
	}

	private void checkBarcode() {
		Intent intent = new Intent("com.google.zxing.client.android.SCAN");
		//intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
		try
		{
			startActivityForResult(intent, BARCODE);
		}
		catch(Exception e)
		{
			Toast.makeText(this, R.string.view_error_barcode,
					Toast.LENGTH_LONG).show();
		}
	}

	private void displayAbout() {
		new AlertDialog.Builder(this).setMessage(R.string.about_text).
		setPositiveButton(android.R.string.ok, null).show();
	}

	private void displayHelp() {

		new AlertDialog.Builder(this).setMessage(R.string.help_main)
		.setPositiveButton(android.R.string.ok, null).
		show();

	}

	private void createHost() {
		Intent i = new Intent(this, HostAdd.class);
		startActivityForResult(i, ADDHOST);

	}

	private void launchSettings()
	{
		Intent i = new Intent(this, Preferences.class);
		startActivity(i);
	}

	protected void onListItemClick(ListView l, View v, int position, long id) {

		Host host;

		super.onListItemClick(l, v, position, id);

		host = (Host) getListView().getItemAtPosition(position);
		showHost(host);
	}

	private void showHost(Host host)
	{
		if(host != null)
		{
			Intent i = new Intent(this, HostView.class);

			i.putExtra(Host.NAME, host.getName());
			i.putExtra(Host.STATUS, host.getStatus());
			i.putExtra(Host.COMMENT, host.getComment());
			i.putExtra(Host.SSHUSER, host.getSshUser());
			i.putExtra(Host.SSHPORT, host.getSshPort());
			i.putExtra(Host.BARCODE, host.getBarcode());
			i.putExtra(Host.OPTPATH, host.getOptPath());
			i.putExtra(Host.OPTPATH, host.getOptPath());
			i.putExtra(DEFAULT_USER_KEY, user);
			i.putExtra(DEFAULT_PORT_KEY, defaultPort);
			startActivityForResult(i, HOST_VIEW);
		}
	}

	protected void onActivityResult(int requestCode, int resultCode, Intent intent) {

		super.onActivityResult(requestCode, resultCode, intent);
		if(intent == null)
		{
			return;
		}
		Bundle extras = intent.getExtras();

		switch(requestCode) {
		case BARCODE:
			if(extras == null || resultCode == RESULT_CANCELED)
			{
				break;
			}
			String gBarcode = intent.getStringExtra("SCAN_RESULT");
			Log.i("msntop", "Got back bc" + gBarcode);
			searchBarcode(gBarcode);
			break;

		case ADDHOST:
			if(extras == null)
			{
				break;
			}
			String host = extras.getString(Host.NAME);
			if(host == null)
			{
				break;
			}
			String comment = extras.getString(Host.COMMENT);
			String sshUser = extras.getString(Host.SSHUSER);
			if(sshUser == null || "".equals(sshUser))
			{
				sshUser = HostDbAdapter.UNSET_SSHUSER;
			}
			String sshPort = extras.getString(Host.SSHPORT);
			if(sshPort == null || "".equals(sshPort))
			{
				sshPort	= HostDbAdapter.UNSET_SSHPORT;
			}
			String optPath = extras.getString(Host.OPTPATH);
			//Log.i("addhost", "adding " + host + comment + sshUser + sshPort);
			long id = dbHelper.addHost(host, comment, optPath,sshUser, sshPort );

			if(loaded == true)
			{
				addHost(id, host, UPDATING, comment, optPath, sshUser, sshPort);
			}
			//loaded = true;

			//isHostUp2(host);
			//			Log.i("onactivityResult", "Calling fillData");

			break;
		case HOST_VIEW:
			switch(resultCode)
			{
			case HostView.HOST_EDITED:
				editHost(intent);
				break;
			case HostView.HOST_DELETED:
				deleteHost(intent);
				break;
			}
		}
	}

	private void searchBarcode(String barcode2) {

		//		long id = dbHelper.findByBarcode(barcode2);
		//		
		//		if(id < 0)
		//		{
		//			Toast.makeText(Msntop.this, "Barcode does not match a host",
		//					Toast.LENGTH_SHORT).show();
		//		}

		int position = getHostPositionByBarcode(barcode2);
		if(position < 0)
		{
			Toast.makeText(Msntop.this, "Barcode does not match a host",
					Toast.LENGTH_SHORT).show();
			return;
		}

		showHost(hostList.get(position));

	}

	private int getHostPositionByBarcode(String bc)
	{
		int n = hostList.size();
		int i;
		//Log.i("getHostPosition", "Got name to srch " + hostName );
		for(i = 0; i < n; i++)
		{
			if(bc.equals(hostList.get(i).getBarcode()))
			{
				break;
			}

		}

		if(i == n)
		{
			return -1;
		}
		else
		{
			return i;
		}
	}

	private void deleteHost(Intent intent) {

		if(intent == null)
		{
			return;
		}
		Bundle b = intent.getExtras();

		if(b == null)
		{
			return;
		}

		String host = b.getString(Host.NAME);

		if(host == null)
		{
			return;
		}

		int i = getHostPosition(host);

		if(i == -1)
		{
			// Host not found
			return;
		}

		Host h = hostList.remove(i);

		if(h == null)
		{
			return;
		}
		else
		{
			dbHelper.deleteHost(h.getId());
			Toast.makeText(Msntop.this, "Deleted host " + h.getName(),
					Toast.LENGTH_SHORT).show();
			fillData();
		}
	}

	private void editHost(Intent intent) {

		if(intent == null)
		{
			return;
		}
		Bundle extras = intent.getExtras();

		if(extras == null)
		{
			return;
		}

		String name = extras.getString(Host.NAME);
		int position = getHostPosition(name);
		if(position == -1)
		{
			return;
		}
		Host h = hostList.get(position);

		String comment = extras.getString(Host.COMMENT);
		String sshU = extras.getString(Host.SSHUSER);
		String sshP = extras.getString(Host.SSHPORT);
		String barcode = extras.getString(Host.BARCODE);
		String optPath = extras.getString(Host.OPTPATH);

		h.setComment(comment);
		h.setSshUser(sshU);
		h.setSshPort(sshP);
		h.setBarcode(barcode);
		h.setOptPath(optPath);

		dbHelper.updateHost(h.getId(), name, comment, optPath, sshU, sshP);
		Log.i("Got back ", "bc is " + barcode);
		if(dbHelper.updateBarcode(h.getId(), barcode))
		{
			Log.i("Got back ", "UPDATED in DB");
		}
		else
		{
			Log.i("Got back ", "DB FAIL");
		}	

		return;
	}

	private void fillData() {

		//ListAdapter adapter = new HostListAdapter(this, hostList);
		//setListAdapter(adapter);

		SimpleAdapter adapter = new HostAdapter2(this, hostList, R.layout.host_row, 
				new String[] {Host.NAME, Host.STATUS}, 
				new int[] {R.id.text2}  );
		//adapter.setViewBinder(new HostBinder());
		//		Log.e("fillData", "The number of hosts is " + hostList.size());
		setListAdapter(adapter);

		setTitle("HostMon    Last updated: " + getDateTime());
	}

	private String getDateTime() {
		DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
		Date date = new Date();
		return dateFormat.format(date);
	}
	private synchronized void updateResultsInUi(String hostName, int status)
	{
		//Log.i("updtResultsUI", "Host name is " + hostName + "Status is :" +status);
		int position = getHostPosition(hostName);

		if(position == -1)
		{
			//Log.e("updateResultsinUi", "hostName is not found in host");
		}
		else
		{
			updateItem(position, status);
		}
	}

	private synchronized int getHostPosition(String hostName)
	{
		int n = hostList.size();
		int i;
		//Log.i("getHostPosition", "Got name to srch " + hostName );
		for(i = 0; i < n; i++)
		{
			if(hostName.equals(hostList.get(i).getName()))
			{
				break;
			}

		}

		if(i == n)
		{
			return -1;
		}
		else
		{
			return i;
		}
	}

	private synchronized void updateResultsInUi(int position, int status)
	{
		Host host;
		//		host = (Host) getListView().getItemAtPosition(position);

		if(hostList == null)
		{
			return;
		}
		host = (Host)hostList.get(ht_id);

		if(host == null)
		{
			//			Log.e("updateItem", "Could not find host object at position" + ht_id );
			return;
		}

		if(ht_status == PING_OK)
		{
			host.setStatus(UP);
		}
		else
		{
			host.setStatus(DOWN);
		}
		setProcessFlag(0);
		// TODO - We must change only the specific item;
		//		Log.i("updateResultinUI", "Calling fillData");
		fillData();
	}
	private void updateResultsInUi() {
		// TODO Auto-generated method stub
		//Log.i("updateItem", " position" + ht_id + " status " + ht_status);
		updateResultsInUi(ht_id, ht_status);

	}

	private void updateItem(int position, int status)
	{
		//Log.i("updateItem", " position" + position + " status " + status);
		Host host;
		//		host = (Host) getListView().getItemAtPosition(position);
		host = (Host)hostList.get(position);

		if(host == null)
		{
			//			Log.e("updateItem", "Could not find host object at position" + position );
			return;
		}

		if(status == PING_OK)
		{
			host.setStatus(UP);
		}
		else
		{
			host.setStatus(DOWN);
		}

		// TODO - We must change only the specific item;
		//		Log.i("updateitem", "Calling fillData");
		fillData();
	}

	private class HostAdapter2 extends SimpleAdapter
	{

		public HostAdapter2(Context context,
				List<? extends Map<String, ?>> data, int resource,
						String[] from, int[] to) {
			super(context, data, resource, from, to);

		}

		public View getView(int position, View convertView, ViewGroup parent)
		{
			TextView tv = (TextView) super.getView(position, convertView, parent);
			final Map dataSet = (Map) super.getItem(position);
			String stat = (String)(dataSet.get(Host.STATUS));
			if(tv != null)
			{
				if(UP.equals(stat))
				{
					tv.setTextColor(Color.GREEN);
				}
				else if (UPDATING.equals(stat))
				{
					tv.setTextColor(Color.GRAY);
				}
				else
					tv.setTextColor(Color.RED);
			}
			return tv;

		}
	}
}
